package com.leonwoodstudio.eventdetectionclient;

import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.database.sqlite.SQLiteDatabase;
import android.os.Handler;
import android.os.Message;
import android.support.design.widget.NavigationView;
import android.support.design.widget.TabLayout;
import android.support.v4.app.NotificationCompat;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import com.leonwoodstudio.eventdetectionclient.eventmessage.ParsedEventMessageToSave;
import com.leonwoodstudio.eventdetectionclient.utils.DatabaseHelper;
import com.leonwoodstudio.eventdetectionclient.utils.FileAccessor;
import com.leonwoodstudio.eventdetectionclient.utils.Util;

import java.io.File;
import java.util.Properties;

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    /**
     * The {@link android.support.v4.view.PagerAdapter} that will provide
     * fragments for each of the sections. We use a
     * {@link FragmentPagerAdapter} derivative, which will keep every
     * loaded fragment in memory. If this becomes too memory intensive, it
     * may be best to switch to a
     * {@link android.support.v4.app.FragmentStatePagerAdapter}.
     */
    private SectionsPagerAdapter mSectionsPagerAdapter;

    /**
     * The {@link ViewPager} that will host the section contents.
     */
    private ViewPager mViewPager;

    public LatestEventFragment latest_event_fragment;
    public EventHistoryFragment event_history_fragment;

    AlertDialog ip_port_dialog;
    public static String prop_remote_port;
    public static String prop_remote_ip_address;

    public Handler handler;
    public static final int MSG_ACCESS_FILE = 0;
    public static final int MSG_RECV_PIC_URL = 1;
    public static final int MSG_DOWNLOAD_PIC_DONE = 2;
    public static final int MSG_CONNECTION_ESTABLISHED = 3;
    public static final int MSG_CONNECTION_LOST = 4;

    NotificationManager notify_mgr;
    public static SQLiteDatabase event_history_database;

    ReceiveEventThread receive_event_thread;
    String[] event_types;
    AlertDialog quitDialog;
    AlertDialog clear_database_dialog;

    ParsedEventMessageToSave curr_parsed;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(), this);

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.container);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(mViewPager);

        loadProperties();
        buildIpPortDialog();
        createHandler();
        receive_event_thread = new ReceiveEventThread(handler);
        receive_event_thread.start();

        notify_mgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        event_history_database = new DatabaseHelper(this).getWritableDatabase();

        Resources res = getResources();
        event_types = res.getStringArray(R.array.event_type);

        buildQuitDialog();
        buildClearDatabaseDialog();
    }

    private void sendNotificationWithAction() {
        //获取PendingIntent
        Intent mainIntent = new Intent(this, MainActivity.class);
        PendingIntent mainPendingIntent = PendingIntent.getActivity(this, 0, mainIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        //创建 Notification.Builder 对象
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                //点击通知后自动清除
                .setAutoCancel(true)
                .setContentTitle("检测到新事件")
                .setContentText("点我查看新事件")
                //等价于setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE);
                .setDefaults(Notification.DEFAULT_ALL)
                .setContentIntent(mainPendingIntent);
        //发送通知
        notify_mgr.notify(0, builder.build());
    }

    private void createHandler() {
        handler = new Handler() {
            public void handleMessage(Message msg) {// 此方法在ui线程运行
                switch (msg.what) {
                    case MSG_ACCESS_FILE:
                        FileAccessor.getInstance(MainActivity.this);
                        if (loadPropertiesFromExtFileIfExist()) {
                            // build the dialog again to apply ip change if any
                            buildIpPortDialog();
                        }
                        break;
                    case MSG_RECV_PIC_URL: {
                        ParsedEventMessageToSave parsed = (ParsedEventMessageToSave) msg.obj;
                        SaveEventToDatabase(parsed);
                        String event = Util.DateToString(Util.StringToDate(parsed.getDate())) + "\n" + parsed.getCamera_idx() + "号摄像机拍下\n" +
                                parsed.getLane_inx() + "号车道发生 " + event_types[Integer.valueOf(parsed.getEvent_type())] + " 事件\n" + "坐标:X" + parsed.getCoordinate_x() +
                                ", Y" + parsed.getCoordinate_y();
                        curr_parsed = parsed;
                        if (FileAccessor.getInstance(null).isFileExist(FileAccessor.getInstance(null).getFilesDir() + parsed.getPic_name())) {
                            latest_event_fragment.UpdateEvent(event, FileAccessor.getInstance(null).getFilesDir() + parsed.getPic_name());
                        } else {
                            latest_event_fragment.UpdateEvent(event, null);
                        }
                        event_history_fragment.event_history_list_view_adapter.event_history_list.add(0, parsed);
                        event_history_fragment.event_history_list_view_adapter.notifyDataSetChanged();
                        sendNotificationWithAction();
                        break;
                    }
                    case MSG_DOWNLOAD_PIC_DONE: {
                        ParsedEventMessageToSave parsed = (ParsedEventMessageToSave) msg.obj;
                        if (parsed.equals(curr_parsed)) {
                            if (FileAccessor.getInstance(null).isFileExist(FileAccessor.getInstance(null).getFilesDir() + parsed.getPic_name())) {
                                String event = Util.DateToString(Util.StringToDate(parsed.getDate())) + "\n" + parsed.getCamera_idx() + "号摄像机拍下\n" +
                                        parsed.getLane_inx() + "号车道发生 " + event_types[Integer.valueOf(parsed.getEvent_type())] + " 事件\n" + "坐标:X" + parsed.getCoordinate_x() +
                                        ", Y" + parsed.getCoordinate_y();
                                latest_event_fragment.UpdateEvent(event, FileAccessor.getInstance(null).getFilesDir() + parsed.getPic_name());
                            }
                        }
                        // Refresh listview pics
                        event_history_fragment.event_history_list_view_adapter.notifyDataSetChanged();
                        break;
                    }
                    case MSG_CONNECTION_ESTABLISHED:
                        latest_event_fragment.UpdateEvent("已经连接到服务器!", null);
                        break;
                    case MSG_CONNECTION_LOST:
                        latest_event_fragment.UpdateEvent("与服务器断开,正在尝试重连...!", null);
                        break;
                }
            }
        };
    }

    private void SaveEventToDatabase(ParsedEventMessageToSave parsed) {
        ContentValues values = new ContentValues();
        values.put("url", parsed.getUrl());
        values.put("pic_name", parsed.getPic_name());
        values.put("date", parsed.getDate());
        values.put("camera_idx", parsed.getCamera_idx());
        values.put("lane_inx", parsed.getLane_inx());
        values.put("event_type", parsed.getEvent_type());
        values.put("coordinate_x", parsed.getCoordinate_x());
        values.put("coordinate_y", parsed.getCoordinate_y());
        event_history_database.insert(DatabaseHelper.EVENT_HISTORY_TABLE_NAME, null, values);
    }

    private void buildQuitDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("退出")
                .setIcon(android.R.drawable.ic_dialog_info)
                .setMessage("确定要退出吗?")
                .setNegativeButton("取消", null)
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // TODO Auto-generated method stub
                        receive_event_thread.Stop();
                        System.gc();
                        MainActivity.this.finish();
                    }
                });
        quitDialog = builder.create();
    }

    private void buildClearDatabaseDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("清空历史数据")
                .setIcon(android.R.drawable.ic_dialog_info)
                .setMessage("确定要清空历史数据吗?")
                .setNegativeButton("取消", null)
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // TODO Auto-generated method stub
                        event_history_database.delete(DatabaseHelper.EVENT_HISTORY_TABLE_NAME, null, null);
                        event_history_fragment.event_history_list_view_adapter.event_history_list.clear();
                        event_history_fragment.event_history_list_view_adapter.notifyDataSetChanged();
                        // delete pics
                        File dir = new File(FileAccessor.getInstance(MainActivity.this).getFilesDir());
                        if (dir.exists()) {
                            File[] files = dir.listFiles();
                            for (File file : files) {
                                if (file.getAbsolutePath().endsWith(".jpg")) {
                                    file.delete();
                                }
                            }
                        }
                    }
                });
        clear_database_dialog = builder.create();
    }

    private void buildIpPortDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("设置地址端口信息");
        builder.setNegativeButton("取消", null);
        View view = View.inflate(this, R.layout.ip_port_dialog, null);
        builder.setView(view);
        final EditText remote_ip = (EditText) view.findViewById(R.id.remote_ip);
        remote_ip.setText(prop_remote_ip_address);
        final EditText remote_port = (EditText) view.findViewById(R.id.remote_port);
        remote_port.setText(prop_remote_port);
        builder.setIcon(android.R.drawable.ic_dialog_info);
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // TODO Auto-generated method stub
                prop_remote_ip_address = remote_ip.getText().toString();
                prop_remote_port = remote_port.getText().toString();
                Properties props = new Properties();
                props.put(Util.PROPERTIES_KEY_REMOTE_IP_ADDRESS, prop_remote_ip_address);
                props.put(Util.PROPERTIES_KEY_REMOTE_PORT, prop_remote_port);
                Util.saveProperties(props);
            }
        });
        ip_port_dialog = builder.create();
    }

    private void loadProperties() {
        Properties props = Util.getProperties(this);
        prop_remote_port = props.getProperty(Util.PROPERTIES_KEY_REMOTE_PORT);
        prop_remote_ip_address = props.getProperty(Util.PROPERTIES_KEY_REMOTE_IP_ADDRESS);
    }

    private boolean loadPropertiesFromExtFileIfExist() {
        Properties props = Util.getPropertiesFromExtFileIfExist();
        if (props == null) {
            return false;
        }
        prop_remote_port = props.getProperty(Util.PROPERTIES_KEY_REMOTE_PORT);
        prop_remote_ip_address = props.getProperty(Util.PROPERTIES_KEY_REMOTE_IP_ADDRESS);
        return true;
    }

    @Override
    public void onBackPressed() {
        quitDialog.show();
    }

    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.nav_ip_port) {
            ip_port_dialog.show();
        } else if (id == R.id.cleanup_database) {
            clear_database_dialog.show();
        }

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

    /**
     * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
     * one of the sections/tabs/pages.
     */
    public class SectionsPagerAdapter extends FragmentPagerAdapter {
        MainActivity context;

        public SectionsPagerAdapter(FragmentManager fm, Context context) {
            super(fm);
            this.context = (MainActivity)context;
        }

        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    context.latest_event_fragment = new LatestEventFragment();
                    return context.latest_event_fragment;
                case 1:
                    context.event_history_fragment = new EventHistoryFragment();
                    return context.event_history_fragment;
            }
            return null;
        }

        @Override
        public int getCount() {
            // Show 2 total pages.
            return 2;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            switch (position) {
                case 0:
                    return "最新事件";
                case 1:
                    return "历史事件";
            }
            return null;
        }
    }
}
